﻿using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace MvcPresenter.Models
{
	public enum FileType
	{
		Markup,
		StyleSheet,
		Image
	}

	internal static class StorageAccessor
	{
		public const string TempPathName = "MvcPresenter";
		public const string MarkupFileExtension = "markup";
		private static readonly Dictionary<FileType, string> FileTypeFolders = 
			new Dictionary<FileType, string>
           	{
           		{FileType.StyleSheet, "css"},
           		{FileType.Image, "image"},
           		{FileType.Markup, ""},
           	};

		private static string[] LoadFiles(string path, FileType fileType)
		{
			var targetPath = Path.Combine(path, FileTypeFolders[fileType]);
			return Directory.Exists(targetPath) 
			       	? Directory.GetFiles(targetPath)
			       	  	.Select(p => p.Replace(path, "").Trim('\\'))
			       	  	.ToArray()
			       	: new string[] { };
		}

		private static IEnumerable<ResourceFile> LoadResourceFiles(string path, FileType fileType)
		{
			return LoadFiles(path, fileType)
				.Select(p => new ResourceFile
				             	{
				             		FileType = fileType,
				             		FileName = p
				             	});
		}

        private static void LoadAdd<T>(IList<T> list, IEnumerable<T> adds)
        {
            foreach (var add in adds)
                list.Add(add);
        }
		
        public static Presentation Load(string path, bool isTemporary, string name)
		{
			var presentation = new Presentation(isTemporary) {Name = name};
			var loadPath = Path.Combine(path, name);
			var markups = Directory.GetFiles(loadPath, "*." + MarkupFileExtension, SearchOption.TopDirectoryOnly)
				.Select(f => File.ReadAllText(f))
				.Select(text => new Markup(text));

            LoadAdd(presentation.Markups, markups);
            LoadAdd(presentation.Images, LoadResourceFiles(loadPath, FileType.Image));
            LoadAdd(presentation.StyleSheets, LoadResourceFiles(loadPath, FileType.StyleSheet));

			return presentation;
		}

		public static void Save(string fromPath, string toPath, Presentation presentation)
		{
			// 今のファイルを消す
			Delete(toPath, presentation);

			var targetFrom = Path.Combine(fromPath, presentation.Name);
			var targetTo = Path.Combine(toPath, presentation.Name);

			// 一気に移動
			Directory.Move(targetFrom, targetTo);

			// Markupだけ手作り
			for (var i = 0; i < presentation.Markups.Count; i++)
				File.WriteAllText(
					Path.Combine(targetTo, string.Format("{0:000}.{1}", i, MarkupFileExtension)),
					presentation.Markups[i].Text
				);

			// 差分ファイルの削除はまだないです。
		}

		public static void Delete(string path, Presentation presentation)
		{
			var target = Path.Combine(path, presentation.Name);
			if (Directory.Exists(target))
				Directory.Delete(target, true);
		}

	}
}